package cn.mdmm.web.interceptor;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import cn.modoumama.common.annotation.Token;
import cn.modoumama.common.utils.AnnotationUtil;

/**
 * Created by kedong on 2017/3/16.
 * 表单重复提交拦截器
 */
public class FormTokenInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        Token annotation = getAnnotation(Token.class, handler);
        if (annotation != null) {
            boolean needSaveSession = annotation.save();
            if (needSaveSession) {
                request.getSession(false).setAttribute("token", UUID.randomUUID().toString());
            }
            boolean needRemoveSession = annotation.remove();
            if (needRemoveSession) {
                if (isRepeatSubmit(request)) {
                    return false;
                }
                request.getSession(false).removeAttribute("token");
            }
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }


    private <T extends Annotation> T getAnnotation(Class<T> clazz, Object handler) {
        T t = null;
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            t = AnnotationUtil.findAnnotation(method, clazz);
        }
        return t;
    }

    private boolean isRepeatSubmit(HttpServletRequest request) {
        String serverToken = (String) request.getSession(false).getAttribute("token");
        if (serverToken == null) {
            return true;
        }
        String clinetToken = request.getParameter("token");
        return clinetToken == null || !serverToken.equals(clinetToken);
    }
}
